/*!
 * jRaiser Module Development Kit
 * Document comment parser (2013-02-26T17:28:51+0800)
 * http://jraiser.org/ | Released under MIT license
 */

var util = require('./lib/util');
var member = require('./lib/member');


// 为目标添加特性
function addFeature(target, feature) {
	target.$features = target.$features || [ ];
	target.$features.push(feature);
}

var re_brace = /^\s*\{(.*?)\}\s*/;

// 各种标签的解析器
var parsers = {
	// 模块
	'@module': function(obj, content) {
		obj.$name = content;
		obj.$tag = 'module';
	},
	// 模块分类
	'@category': function(obj, content) {
		if (obj.$tag === 'module') { obj.$category = content; }
	},
	// 包含其他文档
	'@includeFor': function(obj, content) {
		var $type = '';
		content = content.replace(re_brace, function($0, $1) {
			$type = $1;
			return '';
		});
		obj.$include = {
			$for: $type,
			$list: content.split(/\s*,\s*/)
		};
	},
	// 忽略生成此模块的文档
	'@ignore': function(obj, content) { obj.$ignore = true; },
	// 文档指向外部链接
	'@see': function(obj, content) { obj.$see = content; },

	// 描述
	'': function(obj, content) { obj.$description = content; },
	// 所属
	'@for': function(obj, content) { obj.$for = content; },

	// 类型
	'@class': function(obj, content) {
		obj.$name = content;
		obj.$tag = 'class';
	},
	// 继承
	'@extends': function(obj, content) { obj.$extends = content; },
	// 构造函数
	'@constructor': function(obj, content) {
		if (obj.$tag === 'class') {
			obj.$constructor = true;
		} else {
			obj.$tag = 'constructor';
		}
	},
	// 方法
	'@method': function(obj, content) {
		obj.$name = content;
		obj.$tag = 'method';
	},
	// 属性
	'@property': function(obj, content) {
		obj.$name = content;
		obj.$tag = 'property';
	},

	'@type': function(obj, content) {
		obj.$type = util.trimBrace(content);
	},
	// 返回值
	'@return': function(obj, content) {
		var $type;
		content = content.replace(re_brace, function($0, $1) {
			$type = $1;
			return '';
		});

		obj.$return = {
			$type: $type,
			$description: content
		};
	},
	// 函数参数
	'@param': function(obj, content) {
		var $type = '', name = '', optional = false, defaultValue = '';

		content = content.replace(re_brace, function($0, $1) {
			$type = $1;
			return '';
		}).replace(/(.+?)\s+/, function($0, $1) {
			name = $1;
			return '';
		});

		name = name
			.replace(/^\[(.*?)\]/, function($0, $1) {
				optional = true;
				return $1;
			})	// 是否可选参数
			.replace(/=(.*)$/, function($0, $1) {
				defaultValue = $1;
				return '';
			})	// 匹配默认值
			.split('.');

		var parent = obj;
		// 处理多级参数，如 options.data
		name.every(function(s, i) {
			var n = name.slice(0, i + 1).join('.'),
				params = parent.$params = parent.$params || [ ];

			if (i === name.length - 1) {
				var wholeName = n;
				if (defaultValue) {
					wholeName += '=' + defaultValue;
				}
				if (optional) {
					wholeName = '[' + wholeName + ']';
				}
				params.push({
					$name: n,
					$type: $type,
					$description: content,
					$optional: optional,
					$default: defaultValue,
					$wholeName: wholeName
				});
			} else {
				var param;
				params.every(function(p) {
					if (p.$name === n) { param = p; }
					return param == null;
				});
				if (param) {
					parent = param;
					return true;
				} else {
					// 父层级参数不存在，停止循环
					return false;
				}
			}
		});
	},
	// 事件
	'@event': function(obj, content) {
		obj.$tag = 'event';
		obj.$name = content;
	}
};


// 解析注释中的文档内容
exports.parse = function(content) {
	// 匹配出文档注释
	var comments = content.match(/\/\*\*[\w\W]+?\*\//g);

	if (!comments) { return; }

	// 匹配行首的标签
	var rTag = /^(@[^\s]+)\s*/;

	// 模块解析结果
	var module;

	// 中间解析结果
	var tmpResult = [ ];

	// 逐个注释块进行处理
	comments.forEach(function(comment) {
		comment = comment
			.replace(/^\/\*\*[\s\r\n]+/, '')	// 移除 /**
			.replace(/[\s\r\n]+\*\/$/, '')		// 移除 */
			.replace(/^\s*\*\s*/mg, '')			// 移除行首的*
			.replace(/[\r\n]+([^@])/g, '$1')		// 把多行内容替换为一行
			.split(/[\r\n]+/);

		// 存放单个注释块的解析结果
		var obj = { };

		// 单个注释块逐行处理
		comment.forEach(function(line, i) {
			var tag = '';

			line = line.trim().replace(rTag, function($0, $1) {
				tag = $1;
				return '';
			});

			if (parsers[tag]) {
				parsers[tag](obj, line);
			} else {
				addFeature( obj, tag.substr(1) );
			}
		});

		if (obj.$tag === 'module') {
			module = obj;
		} else {
			tmpResult.push(obj);
			// 把构造函数分离出来
			if (obj.$constructor) {
				tmpResult.push({
					$tag: 'constructor',
					$params: obj.$params,
					$for: obj.$name
				});
				delete obj.$params;
				delete obj.$constructor;
			}
		}
	});
	//console.dir(tmpResult);
	if (module) {
		module = new member.$Module(module);
		tmpResult.forEach(function(obj) {
			module.createMember(obj);
		});
		module.$savePath = module.$name
			.replace(/[\/\\]/g, '-')
			.replace(/-+$/g, '');
	}

	return module;
};